package main

import (
	"fmt"
	"sync"
)

type Set struct {
	SetM    map[interface{}]int
	rwMutex sync.RWMutex
}

func NewSet(args ...interface{}) *Set {
	s := &Set{
		SetM:    make(map[interface{}]int),
		rwMutex: sync.RWMutex{},
	}
	for _, arg := range args {
		switch arg := arg.(type) {
		case map[string]int:
			for k := range arg {
				s.SetM[k] += 1
			}
		case map[int]int:
			for k := range arg {
				s.SetM[k] += 1
			}
		case []string:
			for _, k := range arg {
				s.SetM[k] += 1
			}
		case []int:
			for _, k := range arg {
				s.SetM[k] += 1
			}
		case int:
			s.SetM[arg] += 1
		case string:
			s.SetM[arg] += 1
		case Set:
			s.Update(&arg)

		}
	}
	return s
}

func (s *Set) String() string {
	ns := make([]interface{}, 0)
	for k := range s.SetM {
		ns = append(ns, k)
	}
	return fmt.Sprintf("%v", ns)
}

func (s *Set) Add(k interface{}) {
	s.rwMutex.Lock()
	s.SetM[k] += 1
	s.rwMutex.Unlock()
}

func (s *Set) Remove(k interface{}) {
	s.rwMutex.Lock()
	delete(s.SetM, k)
	s.rwMutex.Unlock()

}

func (s *Set) Update(ns *Set) {
	s.rwMutex.Lock()
	for k := range ns.SetM {
		s.SetM[k] += 1
	}
	s.rwMutex.Unlock()
}

func (s *Set) Pop() interface{} {
	for k := range s.SetM {
		s.rwMutex.Lock()
		delete(s.SetM, k)
		s.rwMutex.Unlock()
		return k
	}
	return nil
}

func (s *Set) Intersection(sl *Set) *Set {
	ns := NewSet()
	s.rwMutex.RLock()
	for k := range sl.SetM {
		if _, ok := s.SetM[k]; ok {
			ns.SetM[k] += 1
		}
	}
	s.rwMutex.RUnlock()
	return ns
}

func (s *Set) symmetric_difference(s1 *Set) *Set {
	ns := NewSet()
	s.rwMutex.RLock()
	for k := range s1.SetM {
		if _, ok := s.SetM[k]; !ok {
			ns.SetM[k] += 1
		}
	}

	for k := range s.SetM {
		if _, ok := s1.SetM[k]; !ok {
			ns.SetM[k] += 1
		}
	}
	s.rwMutex.RUnlock()
	return ns
}

func main() {
	s1 := []string{"apple", "banana", "cherry"}
	s2 := []string{"google", "runoob", "apple"}

	set1 := NewSet(s1, 1, 2, 3, 4)
	set2 := NewSet(s2)

	fmt.Println(set1, set2)
	fmt.Println(set1.Intersection(set2))
	fmt.Println(set1.symmetric_difference(set2))

}

// 可以试下定义出来的是不是相等的